package com.gitee.apecome.core.spring;

import com.gitee.apecome.core.annotation.ApeRpcReference;
import com.gitee.apecome.core.remote.consumer.ApeRpcReferenceBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

@Component
public class ApeRpcSpringFactory extends InstantiationAwareBeanPostProcessorAdapter implements InitializingBean, DisposableBean, BeanFactoryAware {

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

    }

    @Override
    public void destroy() throws Exception {

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 启动netty服务  服务元数据注册以及拉去服务 reference数据
        System.out.println("client ===================");
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                boolean isPresent = field.isAnnotationPresent(ApeRpcReference.class);
                if (isPresent) {
                    if (!field.getType().isInterface()) {
                        throw new RuntimeException("it must be interface");
                    }
                    ApeRpcReferenceBean referenceBean = ApeRpcReferenceBean.builder()
                            .address("127.0.0.1:7000") // 这里address 中间需要进行拉去服务信息 这里省略
                            .itface(field.getType())
                            .build();
                    Object proxyObj = null;
                    try {
                        proxyObj = referenceBean.getProxyObject();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    field.setAccessible(true);
                    field.set(bean, proxyObj);
                }
            }
        });

        return super.postProcessAfterInstantiation(bean, beanName);
    }
}
